package com.etonenet.service.system.security;

import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.etonenet.entity.system.UserLogin;
import com.etonenet.enums.userlogin.LoginSucc;
import com.etonenet.repository.system.security.UserLoginRepository;
import com.etonenet.util.DateUtil;
import com.etonenet.util.JsonUtil;
import com.etonenet.util.ServletUtil;

@Component
public class LoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

	private Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private UserLoginRepository userLoginEm;

	private RequestCache requestCache = new HttpSessionRequestCache();

	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {

		String username = request.getParameter("username");
		String password = request.getParameter("password");
		logger.debug("login successed in login:" + username);

		Object o = authentication.getPrincipal();
		if (o instanceof CustomUser) {

			CustomUser customUser = (CustomUser) o;

			// 记录登录信息
			UserLogin ul = new UserLogin();
			ul.setIp(request.getRemoteAddr());
			ul.setIsSuc(LoginSucc.YES.getValue());
			ul.setLoginTime(DateUtil.getCurrentTimestamp());
			ul.setLoginName(username);
			userLoginEm.save(ul);
			logger.debug("login log recorded");

			// TODO oauth token
			// MultiValueMap<String, String> params = new
			// LinkedMultiValueMap<String, String>();
			// params.add("username", username);
			// params.add("password", password);
			// params.add("grant_type", "password");
			//
			// String oauthPath = request.getScheme() + "://localhost:" +
			// request.getServerPort()
			// + request.getContextPath() + "/api/oauth/token";
			// logger.debug("get token from oauth url:" + oauthPath);
			// UriComponents uriComponents =
			// UriComponentsBuilder.fromHttpUrl(oauthPath).queryParams(params).build();
			//
			// @SuppressWarnings("unchecked")
			// Map<String, String> re = new
			// RestTemplate().postForObject(uriComponents.toUri(), null,
			// Map.class);
			// customUser.setOauthToken(re.get("access_token"));
		}

		// 获得登录成功后的跳转url
		SavedRequest savedRequest = requestCache.getRequest(request, response);

		if (savedRequest == null) {
			doSendRedirect(request, response);
			return;
		}

		String targetUrlParameter = getTargetUrlParameter();
		if (isAlwaysUseDefaultTargetUrl()
				|| (targetUrlParameter != null && StringUtils.hasText(request.getParameter(targetUrlParameter)))) {
			requestCache.removeRequest(request, response);
			doSendRedirect(request, response);
			return;
		}

		clearAuthenticationAttributes(request);

		// Use the DefaultSavedRequest URL
		doSendRedirect(request, response, savedRequest.getRedirectUrl());
	}

	public void setRequestCache(RequestCache requestCache) {
		this.requestCache = requestCache;
	}

	private void doSendRedirect(HttpServletRequest request, HttpServletResponse response) throws IOException {

		doSendRedirect(request, response, determineTargetUrl(request, response));
	}

	private void doSendRedirect(HttpServletRequest request, HttpServletResponse response, String targetUrl)
			throws IOException {

		if (ServletUtil.isXhr(request)) {
			HashMap<String, String> map = new HashMap<String, String>();
			map.put("succ", targetUrl);
			String result = JsonUtil.objectToJson(map);

			OutputStream os = null;
			try {
				os = response.getOutputStream();
				os.write(result.getBytes());
				os.flush();
			} finally {
				if (os != null)
					os.close();
			}
		} else
			getRedirectStrategy().sendRedirect(request, response, targetUrl);
	}
}
